package com.wf.ew.store.controller;

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.wf.ew.common.DataUtil;
import com.wf.ew.common.JsonResult;
import com.wf.ew.common.PageResult;
import com.wf.ew.common.utils.UUIDUtil;
import com.wf.ew.store.model.StoreApp;
import com.wf.ew.store.service.StoreAppService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.wf.jwtp.annotation.RequiresPermissions;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.gridfs.GridFsCriteria.whereFilename;

@Api(value = "商店App控制器", tags = "store_app")
@RestController
@RequestMapping("store/app")
public class StoreAppConController {
    @Autowired
    private StoreAppService storeAppService;

    @Autowired
    private GridFsTemplate gridFsTemplate;

    @Autowired
    private GridFSBucket gridFSBucket;


    @RequiresPermissions("get:/v1/app")
    @ApiOperation(value = "查询所有用户", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", required = true, dataType = "Integer", paramType = "form"),
            @ApiImplicitParam(name = "limit", value = "每页多少条", required = true, dataType = "Integer", paramType = "form"),
            @ApiImplicitParam(name = "access_token", value = "令牌", required = true, dataType = "String", paramType = "form")
    })
    @GetMapping()
    public PageResult<StoreApp> list(Integer page, Integer limit) {
        return storeAppService.list(page, limit);
    }


    @RequiresPermissions("post:/v1/app/upload")
    @ApiOperation(value = "上传文件", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件流", required = true, dataType = "File", paramType = "form")
    })
    @PostMapping("/upload")
    public Object uploadFile(@RequestParam("file") MultipartFile multiportFile) throws Exception {
        String fileName = multiportFile.getOriginalFilename() + UUIDUtil.randomUUID8();
        // 获得文件输入流
        InputStream ins = multiportFile.getInputStream();
        // 获得文件类型
        String contentType = multiportFile.getContentType();
        // 将文件存储到mongodb中,mongodb 将会返回这个文件的具体信息
        ObjectId id = gridFsTemplate.store(ins, fileName, contentType);

        Map<String, Object> map = new HashMap<>();
        map.put("filename", fileName);
        map.put("fileid", id);
        return DataUtil.success("success", map);
    }


    @RequiresPermissions("get:/v1/app/download")
    @ApiOperation(value = "下载文件", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "filename", value = "文件名", required = true, dataType = "String", paramType = "form"),
    })
    @GetMapping("/download")
    public void download(HttpServletResponse resp, String filename) throws Exception{
        GridFSFile file = gridFsTemplate.findOne(query(whereFilename().is(filename)));
        if(file != null){
            System.out.println("_id:"+file.getId());
            System.out.println("_objectId:"+file.getObjectId());
            GridFSDownloadStream in =gridFSBucket.openDownloadStream(file.getObjectId());
            GridFsResource resource = new GridFsResource(file,in);
            InputStream inputStream = resource.getInputStream();
            // 获取绑定了客户端的流
            ServletOutputStream output = resp.getOutputStream();
            // 把输入流中的数据写入到输出流中
            IOUtils.copy(inputStream,output);
            inputStream.close();
        }

    }


}
